home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianTrackControls.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
63KB
|
2,775 lines
/*ScianTrackControls.c
Eric Pepke
7 February 1993
Track controls for SciAn
Track controls are used to edit time tracks, such as for keyframe animation.
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianLists.h"
#include "ScianControls.h"
#include "ScianButtons.h"
#include "ScianTitleBoxes.h"
#include "ScianTextBoxes.h"
#include "ScianColors.h"
#include "ScianIDs.h"
#include "ScianSliders.h"
#include "ScianArrays.h"
#include "ScianErrors.h"
#include "ScianWindows.h"
#include "ScianObjWindows.h"
#include "ScianDraw.h"
#include "ScianIcons.h"
#include "ScianMethods.h"
#include "ScianStyle.h"
#include "ScianHelp.h"
#include "ScianPreferences.h"
#include "ScianSymbols.h"
#include "ScianTrackControls.h"
#include "ScianEvents.h"
#include "ScianTimers.h"
#include "ScianScripts.h"
#include "ScianFontSystem.h"
#define DENSITYFACTOR 1.50
#define CEDGE 3 /*Edge in control*/
#define MINNAMESPACE 90
#define MINNOTNAMESPACE 130
ObjPtr densityButtonClass;
ObjPtr pictureButtonClass;
/*Internal prototypes*/
#ifdef PROTO
static int TimeToPixel(ObjPtr control, real time);
static real PixelToTime(ObjPtr, int);
#else
static int TimeToPixel();
static real PixelToTime();
#endif
real timeSteps[] =
{
0.001,
0.05,
0.1,
0.25,
0.5,
1.0,
5.0,
10.0,
15.0,
30.0,
60.0,
300.0,
600.0,
900.0,
1800.0,
3600.0
};
static ObjPtr trackControlClass; /*Class of all track controls*/
#ifdef PROTO
void CalcGeneralSteps(double diff, int pixWidth, int minMajorPix, int minMinorPix, int nSteps, real *steps, double *majorWidth, double *minorWidth)
#else
void CalcGeneralSteps(diff, pixWidth, minMajorPix, minMinorPix, nSteps, steps, majorWidth, nMinorSteps)
double diff;
int pixWidth;
int minMajorPix;
int minMinorPix;
int nSteps;
real *steps;
double *majorWidth;
double *minorWidth;
#endif
/*Calculates good steps for a general scale
diff is the difference between minimum and max
pixWidth is the width in pixels between minimum and max
minMajorPix is the minimum number of pixels between major tics
minMinorPix is the minimum number of pixels between minor tics
nSteps is the number of elements in the steps array
steps is an array of strictly ascending real numbers giving steps
*majorWidth will be the width of a major step
*minorWidth will be the width of a minor step
If steps doesn't get big enough, the function will go up in 5, 10 increments
until arriving at a good value. If steps doesn't get small enough, the
function will return the smallest possibility.
*/
{
Bool majorSet;
Bool minorSet;
int testPixelWidth;
int k;
Bool fiveP;
real step;
/*Start off with neither set*/
majorSet = minorSet = false;
/*First excessive increment will be a five*/
for (k = 0; !(majorSet && minorSet); ++k)
{
if (k < nSteps)
{
step = steps[k];
}
else
{
if (fiveP)
{
step *= 5.0;
fiveP = false;
}
else
{
step *= 2.0;
fiveP = true;
}
}
testPixelWidth = step / diff * pixWidth;
if (!majorSet)
{
if (testPixelWidth > minMajorPix)
{
majorSet = true;
*majorWidth = step;
}
}
if (!minorSet)
{
if (testPixelWidth > minMinorPix)
{
minorSet = true;
*minorWidth = step;
}
}
}
}
#define DBINSET 5
static ObjPtr DrawDensityButtonContents(theButton)
ObjPtr theButton;
/*Draws the contents of a density button*/
{
int l, r, b, t;
int x;
int step;
ObjPtr var;
var = GetIntVar("DrawDensityButtonContents", theButton, TICDENSITY);
if (!var)
{
return ObjFalse;
}
step = GetInt(var);
Get2DIntBounds(theButton, &l, &r, &b, &t);
for (x = l + DBINSET; x < r - DBINSET; x += step)
{
DrawUILine(x, t - DBINSET - 1, x, b + DBINSET, UIBLACK);
}
return ObjTrue;
}
static ObjPtr DrawPictureButton(theButton)
ObjPtr theButton;
/*Method to draw a picture button. Adapted from DrawButtonObj*/
{
#ifdef GRAPHICS
int left, right, bottom, top;
int depth;
Bool hilight, active;
ObjPtr theLabel;
char *label;
ObjPtr theColor;
int color;
FuncTyp method;
if (!Get2DIntBounds(theButton, &left, &right, &bottom, &top))
{
return NULLOBJ;
}
if (IsDrawingRestricted(left, right, bottom, top))
{
return ObjFalse;
}
hilight = GetPredicate(theButton, HIGHLIGHTED);
active = GetPredicate(theButton, ACTIVATED);
theLabel = GetVar(theButton, NAME);
if (theLabel)
{
label = GetString(theLabel);
}
else
{
label = (char *) NIL;
}
theColor = GetVar(theButton, COLOR);
if (!theColor)
{
color = UIBACKGROUND;
}
else
{
color = GetPredicate(theButton, VALUE) ? GetInt(theColor) : UIBACKGROUND;
}
if (!active)
{
BeginTranslucent();
DrawRaisedRect(left, right, bottom, top, hilight ? UIHIBACKGROUND : color);
EndTranslucent();
}
else
{
DrawRaisedRect(left, right, bottom, top, hilight ? UIHIBACKGROUND : color);
}
/*Draw the stuff on the top here*/
method = GetMethod(theButton, DRAWCONTENTS);
if (method)
{
(*method)(theButton);
}
return ObjTrue;
#endif /* GRAPHICS */
}
#ifdef PROTO
ObjPtr NewDensityButton(int l, int r, int b, int t, char *name, int density)
#else
ObjPtr NewDensityButton(l, r, b, t, name, density)
int l; int r; int b; int t; char *name; int density;
#endif
/*Creates a new density button*/
{
ObjPtr retVal;
retVal = NewObject(densityButtonClass, 0L);
Set2DIntBounds(retVal, l, r, b, t);
SetVar(retVal, VALUE, NewInt(0));
SetVar(retVal, HIGHLIGHTED, ObjFalse);
SetVar(retVal, NAME, NewString(name));
SetVar(retVal, ACTIVATED, ObjTrue);
SetVar(retVal, TICDENSITY, NewInt(density));
return retVal;
}
#ifdef PROTO
static int TimeToPixel(ObjPtr control, real time)
#else
static int TimeToPixel(control, time)
ObjPtr control;
real time;
#endif
/*Returns the x pixel for a specific time in a track control.
Check this against bounds of thing before drawing*/
{
ObjPtr var, scrollbar;
real value, tpp;
int l, r, b, t, mid;
int leftWidth;
int pixWidth;
Get2DIntBounds(control, &l, &r, &b, &t);
var = GetIntVar("PixelToTime", control, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
l += leftWidth + 2 * TC_GAP + BARWIDTH + 1;
--r;
pixWidth = r - l;
MakeVar(control, TIMEPERPIXEL);
var = GetRealVar("PixelToTime", control, TIMEPERPIXEL);
if (var)
{
tpp = GetReal(var);
}
else
{
tpp = 0.1;
}
mid = (l + r) / 2;
scrollbar = GetVar(control, HSCROLL);
if (scrollbar)
{
var = GetValue(scrollbar);
if (var)
{
value = GetReal(var);
}
else
{
value = 0.0;
}
}
else
{
value = 0.0;
}
return (time - value) / tpp + 0.5 + mid;
}
static real PixelToTime(control, pixel)
ObjPtr control;
int pixel;
/*Returns the time for a specific x pixel in a track control.
Check this against bounds of thing before drawing*/
{
ObjPtr var, scrollbar;
real value, tpp;
int l, r, b, t, mid;
int leftWidth;
int pixWidth;
Get2DIntBounds(control, &l, &r, &b, &t);
var = GetIntVar("PixelToTime", control, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
l += leftWidth + 2 * TC_GAP + BARWIDTH + 1;
--r;
pixWidth = r - l;
MakeVar(control, TIMEPERPIXEL);
var = GetRealVar("PixelToTime", control, TIMEPERPIXEL);
if (var)
{
tpp = GetReal(var);
}
else
{
tpp = 0.1;
}
mid = (l + r) / 2;
scrollbar = GetVar(control, HSCROLL);
if (scrollbar)
{
var = GetValue(scrollbar);
if (var)
{
value = GetReal(var);
}
else
{
value = 0.0;
}
}
else
{
value = 0.0;
}
return (pixel - mid) * tpp + value;
}
static ObjPtr ChangeTrackControlVScroll(scrollbar)
ObjPtr scrollbar;
/*Changes in response to a vertical scrollbar*/
{
ObjPtr repObj;
int l, r, b, t, dummy;
repObj = GetVar(scrollbar, REPOBJ);
if (repObj)
{
Get2DIntBounds(repObj, &l, &r, &dummy, &dummy);
Get2DIntBounds(scrollbar, &dummy, &dummy, &b, &t);
ImInvalidBounds(repObj, l + 1, r - 1, b + 1, t - 1);
}
return ObjTrue;
}
static ObjPtr ChangeTrackControlHScroll(scrollbar)
ObjPtr scrollbar;
/*Changes in response to a horizontal scrollbar*/
{
ObjPtr repObj;
int l, r, b, t, dummy;
repObj = GetVar(scrollbar, REPOBJ);
if (repObj)
{
Get2DIntBounds(scrollbar, &l, &r, &dummy, &dummy);
Get2DIntBounds(repObj, &dummy, &dummy, &b, &t);
ImInvalidBounds(repObj, l + 1, r - 1, b + 1, t - 1);
}
return ObjTrue;
}
static ObjPtr MakeDenser(button)
ObjPtr button;
/*Makes a track control denser*/
{
ObjPtr repObj, var;
repObj = GetObjectVar("MakeDenser", button, REPOBJ);
if (!repObj)
{
return ObjFalse;
}
MakeVar(repObj, TIMEPERPIXEL);
var = GetVar(repObj, TIMEPERPIXEL);
if (var)
{
SaveForUndo(repObj);
SetVar(repObj, TIMEPERPIXEL, NewReal(GetReal(var) * DENSITYFACTOR));
RecalcScroll(repObj);
return ObjTrue;
}
return ObjFalse;
}
static ObjPtr MakeSparser(button)
ObjPtr button;
/*Makes a track control sparser*/
{
ObjPtr repObj, var;
repObj = GetObjectVar("MakeSparser", button, REPOBJ);
if (!repObj)
{
return ObjFalse;
}
MakeVar(repObj, TIMEPERPIXEL);
var = GetVar(repObj, TIMEPERPIXEL);
if (var)
{
SaveForUndo(repObj);
SetVar(repObj, TIMEPERPIXEL, NewReal(GetReal(var) / DENSITYFACTOR));
RecalcScroll(repObj);
return ObjTrue;
}
return ObjFalse;
}
#ifdef PROTO
ObjPtr NewTrackControl(int l, int r, int b, int t, char *name, real low, real high)
#else
ObjPtr NewTrackControl(l, r, b, t, name, low, high)
int l, r, b, t;
char *name;
real low, high;
#endif
/*Returns a new track control*/
{
ObjPtr retVal, scrollbar, readout, button;
int leftWidth;
real min, max, portionShown;
ObjPtr var;
retVal = NewObject(trackControlClass, 0L);
if (!retVal)
{
return NULLOBJ;
}
Set2DIntBounds(retVal, l, r, b, t);
SetVar(retVal, NAME, NewString(name));
/*Find out parameters of the control*/
var = GetIntVar("NewTrackControl", retVal, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
/*Create the scroll bars*/
#ifdef SCROLLINMIDDLE
scrollbar = NewScrollbar(l + leftWidth + TC_GAP, l + leftWidth + TC_GAP + BARWIDTH,
b + BARWIDTH + TC_GAP,
t - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP,
"Track Scroll");
#else
scrollbar = NewScrollbar(l, l + BARWIDTH,
b + BARWIDTH + TC_GAP,
t - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP,
"Track Scroll");
#endif
SetVar(scrollbar, PARENT, retVal);
SetVar(scrollbar, REPOBJ, retVal);
SetMethod(scrollbar, CHANGEDVALUE, ChangeTrackControlVScroll);
SetVar(retVal, VSCROLL, scrollbar);
scrollbar = NewScrollbar(l + leftWidth + 2 * TC_GAP + BARWIDTH, r,
b,
b + BARWIDTH,
"Time Scroll");
SetVar(scrollbar, PARENT, retVal);
SetVar(scrollbar, REPOBJ, retVal);
SetMethod(scrollbar, CHANGEDVALUE, ChangeTrackControlHScroll);
SetVar(retVal, HSCROLL, scrollbar);
/*Create the time readout*/
readout = NewTextBox(l + TC_LEFTLABEL, l + leftWidth + TC_GAP + BARWIDTH,
t - TC_TIMEHEIGHT + TC_GAP, t,
EDITABLE + WITH_PIT + ONE_LINE, "Time Readout", "0.0");
/*
SetMethod(readout, CHANGEDVALUE, ChangeTrackTimeReadout);
*/
SetVar(readout, PARENT, retVal);
SetTextAlign(readout, RIGHTALIGN);
SetVar(retVal, READOUT, readout);
/*Create the frame readout*/
readout = NewTextBox(l + TC_LEFTLABEL, l + leftWidth + TC_GAP + BARWIDTH,
t - TC_TIMEHEIGHT - TC_CURHEIGHT, t - TC_TIMEHEIGHT,
EDITABLE + WITH_PIT + ONE_LINE, "Frame Readout", "0");
/*
SetMethod(readout, CHANGEDVALUE, ChangeTrackFrameReadout);
*/
SetVar(readout, PARENT, retVal);
SetTextAlign(readout, RIGHTALIGN);
SetVar(retVal, READOUT2, readout);
SetVar(retVal, LOVALUE, NewReal(low));
SetVar(retVal, HIVALUE, NewReal(high));
SetVar(retVal, TIMEPERPIXEL, NewReal(TC_TPP));
portionShown = (r - (l + leftWidth + TC_GAP * 2 + BARWIDTH) - 2) * TC_TPP;
min = low + portionShown * (0.5 - TC_MARGIN);
max = high - portionShown * (0.5 - TC_MARGIN);
if (min > max)
{
min = (min + max) * 0.5;
max = min;
}
SetSliderValue(scrollbar, min);
SetSliderRange(scrollbar, min, max, portionShown / 10.0);
SetVar(retVal, FRAMERATE, NewReal(30.0));
SetVar(retVal, VALUE, NewReal(low));
/*Now make buttons*/
button = NewDensityButton(l + leftWidth - TC_DBWIDTH,
l + leftWidth,
b, b + BARWIDTH, "Expand", 6);
SetVar(button, PARENT, retVal);
SetVar(retVal, SPARSERBUTTON, button);
SetVar(button, REPOBJ, retVal);
SetMethod(button, CHANGEDVALUE, MakeSparser);
button = NewDensityButton(l + leftWidth - TC_DBWIDTH * 2 - TC_GAP,
l + BARWIDTH + leftWidth - BARWIDTH - TC_DBWIDTH - TC_GAP,
b, b + BARWIDTH, "Contract", 3);
SetVar(button, PARENT, retVal);
SetVar(retVal, DENSERBUTTON, button);
SetVar(button, REPOBJ, retVal);
SetMethod(button, CHANGEDVALUE, MakeDenser);
return retVal;
}
ObjPtr DrawTrackControl(object)
ObjPtr object;
/*Draws a track control*/
{
#ifdef GRAPHICS
ObjPtr hScroll, vScroll, readout, var, timeVar, button;
int left, right, bottom, top, timePix, x, y, height;
long k, lowestTrack;
int shownHeight;
real value;
long downOffset;
long line;
int leftWidth;
ObjPtr repObj;
ObjPtr tracks;
ObjPtr *elements;
real loValue, hiValue;
Get2DIntBounds(object, &left, &right, &bottom, &top);
if (IsDrawingRestricted(left, right, bottom, top))
{
return ObjTrue;
}
/*Get the value*/
var = GetRealVar("DrawTrackControl", object, VALUE);
if (var)
{
value = GetReal(var);
}
else
{
value = 0.0;
}
/*Get the low and high values*/
var = GetRealVar("DrawTrackControl", object, LOVALUE);
if (var)
{
loValue = GetReal(var);
}
else
{
loValue = 0.0;
}
var = GetRealVar("DrawTrackControl", object, HIVALUE);
if (var)
{
hiValue = GetReal(var);
}
else
{
hiValue = 0.0;
}
/*Find out parameters of the control*/
var = GetIntVar("DrawTrackControl", object, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
/*Get the repObj*/
repObj = GetVar(object, REPOBJ);
if (repObj)
{
tracks = GetVar(repObj, TRACKS);
}
else
{
tracks = NULLOBJ;
}
SetUIFont(TCFONT);
/*Draw the scroll bars*/
hScroll = GetVar(object, HSCROLL);
if (hScroll)
{
DrawObject(hScroll);
}
vScroll = GetVar(object, VSCROLL);
if (vScroll)
{
DrawObject(vScroll);
}
/*Draw the readouts*/
readout = GetVar(object, READOUT);
if (readout)
{
DrawObject(readout);
}
readout = GetVar(object, READOUT2);
if (readout)
{
DrawObject(readout);
}
/*Draw the buttons*/
button = GetVar(object, DENSERBUTTON);
if (button)
{
DrawObject(button);
}
button = GetVar(object, SPARSERBUTTON);
if (button)
{
DrawObject(button);
}
/*Draw the arrows control*/
x = left + leftWidth + TC_GAP + BARWIDTH / 2;
y = bottom + BARWIDTH / 2;
FillUITri(x - TC_ARROWGAP / 2, y + TC_ARROWSIZE / 2,
x - TC_ARROWGAP / 2 - TC_ARROWSIZE / 2, y,
x - TC_ARROWGAP / 2, y - TC_ARROWSIZE / 2, UIBLACK);
FillUITri(x + TC_ARROWGAP / 2, y - TC_ARROWSIZE / 2,
x + TC_ARROWGAP / 2 + TC_ARROWSIZE / 2, y,
x + TC_ARROWGAP / 2, y + TC_ARROWSIZE / 2, UIBLACK);
FillUIRect(x - TC_VLINEWIDTH / 2, x + TC_VLINEWIDTH / 2,
y - TC_VLINEHEIGHT / 2, y + TC_VLINEHEIGHT / 2, UIBLACK);
/*Draw the track names box*/
#ifdef SCROLLINMIDDLE
FillUIRect(left + 1, left + leftWidth - 1, bottom + TC_GAP + BARWIDTH + 1, top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1, UIGRAY62);
#else
FillUIRect(left + BARWIDTH + TC_GAP + 1, left + BARWIDTH + TC_GAP + leftWidth - 1, bottom + TC_GAP + BARWIDTH + 1, top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1, UIGRAY62);
#endif
/*Get downOffset from vertical scroll bar*/
if (vScroll)
{
downOffset = (long) GetReal(GetValue(vScroll));
}
else
{
downOffset = 0;
}
if (tracks)
{
/*Draw the contents of the tracks*/
elements = ELEMENTS(tracks);
/*Search for a place to begin*/
y = -downOffset;
for (k = 0; k < DIMS(tracks)[0]; ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var)
{
height = GetInt(var);
if ((y - height) < 0) break;
y -= height;
}
}
if (k < DIMS(tracks)[0])
{
/*There's something to print*/
FuncTyp method;
lowestTrack = k;
shownHeight = top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP -
(bottom + TC_GAP + BARWIDTH) - 2;
#ifdef SCROLLINMIDDLE
SetClipRect(left + 1, left + leftWidth - 1, bottom + TC_GAP + BARWIDTH + 1, top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1);
#else
SetClipRect(left + BARWIDTH + TC_GAP + 1, left + BARWIDTH + TC_GAP + leftWidth - 1, bottom + TC_GAP + BARWIDTH + 1, top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1);
#endif
for (k = lowestTrack; (k < DIMS(tracks)[0]) && (y > -shownHeight); ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var)
{
height = GetInt(var);
method = GetMethod(elements[k], DRAWNAME);
if (method)
{
#ifdef SCROLLINMIDDLE
(*method)(elements[k],
left + 1, left + leftWidth - 1,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y - height,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y);
#else
(*method)(elements[k],
left + BARWIDTH + TC_GAP + 1, left + BARWIDTH + TC_GAP + leftWidth - 1,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y - height,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y);
#endif
}
y -= height;
}
}
RestoreClipRect();
}
}
/*Draw the timeline box*/
FillUIRect( left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
top - TC_TIMEHEIGHT,
top - 1,
UIGRAY62);
FillUIRect( left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
top - TC_TIMEHEIGHT - CEDGE,
top - TC_TIMEHEIGHT,
UIBOTTOMEDGE);
FillUIRect( left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
top - TC_TIMEHEIGHT - TC_CURHEIGHT + CEDGE,
top - TC_TIMEHEIGHT - CEDGE,
timeVar ? UIPGREEN : UIGRAY50);
FillUIRect(left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
top - TC_TIMEHEIGHT - TC_CURHEIGHT,
top - TC_TIMEHEIGHT - TC_CURHEIGHT + CEDGE,
UITOPEDGE);
FillUIRect( left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
bottom + TC_GAP + BARWIDTH + 1,
top - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP,
UIGRAY62);
FillUIRect( left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
top - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP,
top - TC_TIMEHEIGHT - TC_CURHEIGHT,
UIGRAY62);
/*Draw the contents of the timeline box*/
if (hScroll)
{
ObjPtr var;
char timeStr[256];
int format;
real timePerPixel, timeAtPixel;
double majorWidth, minorWidth;
double frameWidth;
int curPixel;
int timePixel;
real curTime;
int k;
int pixWidth;
real portionShown;
MakeVar(object, TIMEFORMAT);
var = GetVar(object, TIMEFORMAT);
if (var)
{
format = GetInt(var);
}
else
{
format = TF_SECONDS + TF_SUBSECONDS;
}
/*Draw the time numbers*/
pixWidth = (right - 1) - (left + leftWidth + 2 * TC_GAP + BARWIDTH + 1);
MakeVar(object, TIMEPERPIXEL);
var = GetRealVar("PixelToTime", object, TIMEPERPIXEL);
if (var)
{
portionShown = GetReal(var) * pixWidth;
}
else
{
portionShown = 60.0;
}
timePerPixel = portionShown / ((real) pixWidth);
/*Get the step and tics*/
CalcGeneralSteps(portionShown, pixWidth, TC_MAJORSTEP, TC_MINORSTEP,
sizeof(timeSteps) / sizeof(real), timeSteps,
&majorWidth, &minorWidth);
/*Get a pixel that's way off the left*/
timePixel = left + leftWidth + 2 * TC_GAP + BARWIDTH + 1 - TCMAXTIMEWIDTH;
timeAtPixel = PixelToTime(object, timePixel);
if (timeAtPixel < loValue - minorWidth * 0.5) timeAtPixel = loValue;
timeAtPixel = floor(timeAtPixel / majorWidth) * majorWidth;
timePixel = TimeToPixel(object, timeAtPixel);
/*Write out the times*/
SetClipRect(left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
bottom + 1,
top - 1);
SetUIFont(TCTIMEFONT);
SetUIColor(UIBLACK);
curPixel = timePixel;
curTime = timeAtPixel;
do
{
if (format)
{
PrintTime(timeStr, curTime, format);
}
else
{
sprintf(timeStr, "%g", curTime);
}
if (timeStr[0] == '-') strcat(timeStr, " ");
DrawAString(CENTERALIGN, curPixel,
top - TC_TIMEHEIGHT + 1 + TC_TIMEBOFF,
timeStr);
DrawUILine(curPixel, top - TC_TIMEHEIGHT + TC_TIMEBOFF - 1,
curPixel, top - TC_TIMEHEIGHT, UIBLACK);
#if 0
DrawUILine(curPixel,
bottom + BARWIDTH + TC_GAP + 1, curPixel,
top - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP,
UIBLACK);
#endif
curTime += majorWidth;
curTime = floor(curTime / majorWidth + 0.5) * majorWidth;
curPixel = TimeToPixel(object, curTime);
}
while (curPixel < right + TCMAXTIMEWIDTH &&
curTime < hiValue + minorWidth / 2);
/*Now do minor tics*/
curPixel = timePixel;
curTime = timeAtPixel;
do
{
DrawUILine(curPixel, top - TC_TIMEHEIGHT + TC_TIMEBOFF / 2 - 1,
curPixel, top - TC_TIMEHEIGHT, UIBLACK);
curTime += minorWidth;
curTime = floor(curTime / minorWidth + 0.5) * minorWidth;
curPixel = TimeToPixel(object, curTime);
}
while (curPixel < right &&
curTime < hiValue + minorWidth / 2);
/*Now do frame lines*/
MakeVar(object, FRAMERATE);
var = GetVar(object, FRAMERATE);
if (var)
{
frameWidth = 1.0 / GetReal(var);
/*Get a pixel that's way off the left*/
timePixel = left + leftWidth + 2 * TC_GAP + BARWIDTH;
timeAtPixel = PixelToTime(object, timePixel);
timeAtPixel = floor(timeAtPixel / frameWidth) * frameWidth;
if (timeAtPixel < loValue) timeAtPixel = loValue;
timePixel = TimeToPixel(object, timeAtPixel);
/*Test to see if it's worth doing*/
if (frameWidth / timePerPixel > 6.0)
{
/*Now do minor tics*/
curPixel = timePixel;
curTime = timeAtPixel;
do
{
DrawUILine(curPixel,
bottom + BARWIDTH + TC_GAP + 1, curPixel,
top - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP - 1,
UIGRAY50);
curTime += frameWidth;
curTime = floor(curTime / frameWidth + 0.5) * frameWidth;
curPixel = TimeToPixel(object, curTime);
}
while (curPixel < right &&
curTime < hiValue - frameWidth / 2);
}
}
RestoreClipRect();
/*Draw the tracks*/
if (tracks)
{
/*Draw the contents of the tracks*/
elements = ELEMENTS(tracks);
/*Search for a place to begin*/
y = -downOffset;
for (k = 0; k < DIMS(tracks)[0]; ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var)
{
height = GetInt(var);
if ((y - height) < 0) break;
y -= height;
}
}
if (k < DIMS(tracks)[0])
{
/*There's something to draw*/
FuncTyp method;
real minTime, maxTime;
minTime = PixelToTime(object, left + BARWIDTH + 2 * TC_GAP + leftWidth + 1);
maxTime = PixelToTime(object, right - 1);
lowestTrack = k;
shownHeight = top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP -
(bottom + TC_GAP + BARWIDTH) - 2;
SetClipRect(left + BARWIDTH + 2 * TC_GAP + leftWidth + 1,
right - 1,
bottom + TC_GAP + BARWIDTH + 1,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1);
for (k = lowestTrack; (k < DIMS(tracks)[0]) && (y > -shownHeight); ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var)
{
height = GetInt(var);
method = GetMethod(elements[k], DRAWTRACK);
if (method)
{
(*method)(elements[k],
left + BARWIDTH + 2 * TC_GAP + leftWidth + 1,
right - 1,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y - height,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y,
minTime, maxTime);
}
y -= height;
}
}
RestoreClipRect();
}
}
#if 0
/*Draw the time lines*/
line = (-downOffset / TC_CELLHEIGHT);
if (line < DIMS(datasets)[0])
{
/*It's worth printing*/
int midy;
ObjPtr element;
SetClipRect(left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
bottom + TC_GAP + BARWIDTH + 1,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1);
midy = top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 - (line + 1) * TC_CELLHEIGHT + TCLINEBOFF - downOffset;
SetUIColor(UIBLACK);
while (line < DIMS(datasets)[0] &&
midy > bottom + TC_GAP + BARWIDTH + 1 - TC_CELLHEIGHT)
{
/*Print out the timeline of the object*/
Bool interpolateP;
ObjPtr timeSteps;
element = GetObjectElement(datasets, &line);
MakeVar(element, TIMESTEPS);
timeSteps = GetVar(element, TIMESTEPS);
MakeVar(element, INTERPOLATEP);
interpolateP = GetPredicate(element, INTERPOLATEP);
if (timeSteps)
{
/*Object with time steps. Find the first*/
int pixel;
long ts1, ts2;
real leftTime, rightTime;
/*Get a pixel that's clear off the left side*/
pixel = left;
leftTime = PixelToTime(object, pixel);
/*Get its index*/
ts1 = SearchReal(timeSteps, leftTime);
if (ts1 > 0)
{
--ts1;
}
{
/*There's a chance it can be drawn. Get a pixel
clear off the right*/
pixel = right + TCSAMPLESIZE;
rightTime = PixelToTime(object, pixel);
/*Get its index*/
ts2 = SearchReal(timeSteps, rightTime);
if (ts2 >= DIMS(timeSteps)[0])
{
--ts2;
}
if (ts2 >= ts1)
{
/*DrawIt*/
real *timeElements;
long k;
long coords[2];
int p1, p2;
timeElements = (real *) ELEMENTS(timeSteps);
element = GetObjectElement(datasets, &line);
p1 = TimeToPixel(object, timeElements[ts1]);
for (k = ts1 + 1; k <= ts2; ++k)
{
p2 = TimeToPixel(object, timeElements[k]);
if (!interpolateP)
{
DrawUILine((p1 + p2) / 2, midy + TCMIDTICHEIGHT,
(p1 + p2) / 2, midy - TCMIDTICHEIGHT - 1,
UIBLACK);
DrawUILine((p1 + p2) / 2 + 1, midy + TCMIDTICHEIGHT,
(p1 + p2) / 2 + 1, midy - TCMIDTICHEIGHT - 1,
UIBLACK);
setlinestyle(DASHEDLINE);
}
DrawUILine(p1, midy,
p2, midy,
UIBLACK);
DrawUILine(p1, midy - 1,
p2, midy - 1,
UIBLACK);
if (!interpolateP)
{
setlinestyle(SOLIDLINE);
}
p1 = p2;
}
for (k = ts1; k <= ts2; ++k)
{
pixel = TimeToPixel(object, timeElements[k]);
SetUIColor(TCSAMPLECOLOR);
FillRealQuad((real) pixel, (real) midy + TCSAMPLESIZE / 2,
(real) pixel - TCSAMPLESIZE / 2, (real) midy,
(real) pixel, (real) midy - TCSAMPLESIZE / 2,
(real) pixel + TCSAMPLESIZE / 2, (real) midy);
}
}
}
}
else
{
/*Eternal object*/
SetLineWidth(2);
DrawUILine(left + leftWidth + 2 * TC_GAP + BARWIDTH + 1, midy,
right - 1, midy, TCSAMPLECOLOR);
SetLineWidth(1);
}
midy -= TC_CELLHEIGHT;
++line;
}
RestoreClipRect();
}
#endif
}
if (timeVar == NULLOBJ)
{
FillUIGauzeRect(left + leftWidth + 2 * TC_GAP + BARWIDTH + 1,
right - 1,
top - TC_TIMEHEIGHT - TC_CURHEIGHT,
top - TC_TIMEHEIGHT,
UIBACKGROUND);
}
if (timeVar)
{
timePix = TimeToPixel(object, value);
if (timePix > left + leftWidth + 2 * TC_GAP + BARWIDTH - TCCURWIDTH &&
timePix < right + TCCURWIDTH)
{
/*Draw the time cursor*/
SetClipRect(left + leftWidth + 2 * TC_GAP + BARWIDTH + 1, right - 1, bottom + TC_GAP + BARWIDTH + 1, top - 1);
DrawVCursor(timePix, top - 1 - TC_TIMEHEIGHT + TC_TIMEBOFF, bottom + TC_GAP + BARWIDTH + 1);
DrawRaisedRect(timePix - TCCURWIDTH / 2, timePix + TCCURWIDTH / 2,
top - TC_TIMEHEIGHT - TC_CURHEIGHT + 1 + CEDGE, top - TC_TIMEHEIGHT - 1 - CEDGE,
GetPredicate(object, HIGHLIGHTED) ? UIHIBACKGROUND : UIBACKGROUND);
RestoreClipRect();
}
}
/*Draw the frames of the boxes*/
#ifdef SCROLLINMIDDLE
FrameUIRect(left, left + leftWidth, bottom + TC_GAP + BARWIDTH, top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIBLACK);
#else
FrameUIRect(left + BARWIDTH + TC_GAP, left + BARWIDTH + TC_GAP + leftWidth, bottom + TC_GAP + BARWIDTH, top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIBLACK);
#endif
FrameUIRect(left + leftWidth + 2 * TC_GAP + BARWIDTH,
right,
bottom + TC_GAP + BARWIDTH,
top, UIBLACK);
DrawUILine( left + leftWidth + 2 * TC_GAP + BARWIDTH,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1,
right - 1,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1,
UIBLACK);
/*Draw "Time:" and "Frame:"*/
SetUIColor(UIBLACK);
SetUIFont(TCFONT);
DrawAString(LEFTALIGN, left, top - TC_TIMEHEIGHT + TC_GAP + TC_LABELUP, "Time:");
DrawAString(LEFTALIGN, left, top - TC_TIMEHEIGHT - TC_CURHEIGHT + TC_LABELUP, "Frame:");
#endif
return ObjTrue;
}
ObjPtr ReshapeTrackControl(object, ol, or, ob, ot, left, right, bottom, top)
ObjPtr object;
int ol, or, ob, ot, left, right, bottom, top;
/*Reshapes a track control*/
{
ObjPtr var;
int leftWidth, l, r, b, t, width, height;
int stickiness;
real wr, hr; /*Width and height ratios*/
wr = ((real) (right - left)) / ((real) (or - ol));
hr = ((real) (top - bottom)) / ((real) (ot - ob));
/*Find out parameters of the control*/
var = GetIntVar("DrawTrackControl", object, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
/*Get the current bounds*/
Get2DIntBounds(object, &l, &r, &b, &t);
width = r - l;
height = t - b;
/*Get the object's stickiness*/
var = GetVar(object, STICKINESS);
if (var && IsInt(var))
{
stickiness = GetInt(var);
}
else
{
stickiness = 0;
}
if ((stickiness & STICKYLEFT) || (stickiness & FLOATINGLEFT))
{
if (stickiness & FLOATINGLEFT)
{
l = (l - ol) * wr + left;
}
else
{
l += left - ol;
}
if (!((stickiness & STICKYRIGHT) || (stickiness & FLOATINGRIGHT)))
{
r = l + width;
}
}
if ((stickiness & STICKYRIGHT) || (stickiness & FLOATINGRIGHT))
{
if (stickiness & FLOATINGRIGHT)
{
r = (r - ol) * wr + left;
}
else
{
r += right - or;
}
if (!((stickiness & STICKYLEFT) || (stickiness & FLOATINGLEFT)))
{
l = r - width;
}
}
if ((stickiness & STICKYBOTTOM) || (stickiness & FLOATINGBOTTOM))
{
if (stickiness & FLOATINGBOTTOM)
{
b = (b - ob) * hr + bottom;
}
else
{
b += bottom - ob;
}
if (!((stickiness & STICKYTOP) || (stickiness & FLOATINGTOP)))
{
t = b + height;
}
}
if ((stickiness & STICKYTOP) || (stickiness & FLOATINGTOP))
{
if (stickiness & FLOATINGTOP)
{
t = (t - ob) * hr + bottom;
}
else
{
t += top - ot;
}
if (!((stickiness & STICKYBOTTOM) || (stickiness & FLOATINGBOTTOM)))
{
b = t - height;
}
}
Set2DIntBounds(object, l, r, b, t);
/*Possibly adjust the left width*/
if (r - l - leftWidth < MINNOTNAMESPACE)
{
leftWidth = r - l - MINNOTNAMESPACE;
SetVar(object, LEFTSIDEWIDTH, NewInt(leftWidth));
}
/*Adjust the readouts*/
var = GetVar(object, READOUT);
if (var)
{
Set2DIntBounds(var, l + TC_LEFTLABEL, l + leftWidth + TC_GAP + BARWIDTH,
t - TC_TIMEHEIGHT + TC_GAP, t);
}
var = GetVar(object, READOUT2);
if (var)
{
Set2DIntBounds(var, l + TC_LEFTLABEL, l + leftWidth + TC_GAP + BARWIDTH,
t - TC_TIMEHEIGHT - TC_CURHEIGHT, t - TC_TIMEHEIGHT);
}
/*Adjust the buttons*/
var = GetVar(object, SPARSERBUTTON);
if (var)
{
Set2DIntBounds(var, l + leftWidth - TC_DBWIDTH,
l + leftWidth, b, b + BARWIDTH);
}
var = GetVar(object, DENSERBUTTON);
if (var)
{
Set2DIntBounds(var, l + leftWidth - TC_DBWIDTH * 2 - TC_GAP,
l + BARWIDTH + leftWidth - BARWIDTH - TC_DBWIDTH - TC_GAP,
b, b + BARWIDTH);
}
/*Adjust the scroll bars*/
var = GetVar(object, VSCROLL);
if (var)
{
#ifdef SCROLLINMIDDLE
Set2DIntBounds(var, l + leftWidth + TC_GAP, l + leftWidth + TC_GAP + BARWIDTH,
b + BARWIDTH + TC_GAP,
t - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP);
#else
Set2DIntBounds(var, l, l + BARWIDTH,
b + BARWIDTH + TC_GAP,
t - TC_TIMEHEIGHT - TC_CURHEIGHT - TC_GAP);
#endif
}
var = GetVar(object, HSCROLL);
if (var)
{
Set2DIntBounds(var, l + leftWidth + 2 * TC_GAP + BARWIDTH, r,
b,
b + BARWIDTH);
}
RecalcScroll(object);
return ObjTrue;
}
ObjPtr TrackControlBoundsInvalid(object, changeCount)
ObjPtr object;
unsigned long changeCount;
/*For a time control, tests to see if it needs drawing. Returns
NULLOBJ if it does not
array[4] giving bounds if it does
ObjTrue it it needs to be redrawn but does not know where
*/
{
ObjPtr myBounds;
real boundsElements[4];
real testElements[4];
ObjPtr test;
real myBoundsElements[4];
ObjPtr scrollBar, readout, button;
Bool firstTime = true;
Bool doubleNoBounds = false;
ObjPtr tracks, repObj;
MakeVar(object, APPEARANCE);
MakeVar(object, CHANGEDBOUNDS);
if (GetVarChangeCount(object, CHANGEDBOUNDS) > changeCount)
{
/*Object is not good, so return the bounds*/
myBounds = GetVar(object, CHANGEDBOUNDS);
if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
&& DIMS(myBounds)[0] == 4)
{
return myBounds;
}
else
{
return ObjTrue;
}
}
MakeVar(object, BOUNDS);
myBounds = GetVar(object, BOUNDS);
Array2CArray(myBoundsElements, myBounds);
scrollBar = GetVar(object, HSCROLL);
if (scrollBar);
{
test = BoundsInvalid(scrollBar, changeCount);
if (test)
{
/*Hey, the scroll bar needs redrawing*/
if (IsRealArray(test))
{
/*It has a bounds*/
if (firstTime)
{
Array2CArray(boundsElements, test);
}
else
{
Array2CArray(testElements, test);
if (testElements[0] < boundsElements[0])
boundsElements[0] = testElements[0];
if (testElements[1] > boundsElements[1])
boundsElements[1] = testElements[1];
if (testElements[2] < boundsElements[2])
boundsElements[2] = testElements[2];
if (testElements[3] > boundsElements[3])
boundsElements[3] = testElements[3];
}
}
else
{
/*It doesn't have a bounds*/
if (firstTime)
{
/*Try to use my bounds*/
if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
&& DIMS(myBounds)[0] == 4)
{
Array2CArray(boundsElements, myBounds);
}
else
{
doubleNoBounds = true;
}
}
}
firstTime = false;
}
}
scrollBar = GetVar(object, VSCROLL);
if (scrollBar);
{
test = BoundsInvalid(scrollBar, changeCount);
if (test)
{
/*Hey, the scroll bar needs redrawing*/
if (IsRealArray(test))
{
/*It has a bounds*/
if (firstTime)
{
Array2CArray(boundsElements, test);
}
else
{
Array2CArray(testElements, test);
if (testElements[0] < boundsElements[0])
boundsElements[0] = testElements[0];
if (testElements[1] > boundsElements[1])
boundsElements[1] = testElements[1];
if (testElements[2] < boundsElements[2])
boundsElements[2] = testElements[2];
if (testElements[3] > boundsElements[3])
boundsElements[3] = testElements[3];
}
}
else
{
/*It doesn't have a bounds*/
if (firstTime)
{
/*Try to use my bounds*/
if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
&& DIMS(myBounds)[0] == 4)
{
Array2CArray(boundsElements, myBounds);
}
else
{
doubleNoBounds = true;
}
}
}
firstTime = false;
}
}
readout = GetVar(object, READOUT);
if (readout)
{
test = BoundsInvalid(readout, changeCount);
if (test)
{
/*Hey, the scroll bar needs redrawing*/
if (IsRealArray(test))
{
/*It has a bounds*/
if (firstTime)
{
Array2CArray(boundsElements, test);
}
else
{
Array2CArray(testElements, test);
if (testElements[0] < boundsElements[0])
boundsElements[0] = testElements[0];
if (testElements[1] > boundsElements[1])
boundsElements[1] = testElements[1];
if (testElements[2] < boundsElements[2])
boundsElements[2] = testElements[2];
if (testElements[3] > boundsElements[3])
boundsElements[3] = testElements[3];
}
}
else
{
/*It doesn't have a bounds*/
if (firstTime)
{
/*Try to use my bounds*/
if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
&& DIMS(myBounds)[0] == 4)
{
Array2CArray(boundsElements, myBounds);
}
else
{
doubleNoBounds = true;
}
}
}
firstTime = false;
}
}
readout = GetVar(object, READOUT2);
if (readout)
{
test = BoundsInvalid(readout, changeCount);
if (test)
{
/*Hey, the scroll bar needs redrawing*/
if (IsRealArray(test))
{
/*It has a bounds*/
if (firstTime)
{
Array2CArray(boundsElements, test);
}
else
{
Array2CArray(testElements, test);
if (testElements[0] < boundsElements[0])
boundsElements[0] = testElements[0];
if (testElements[1] > boundsElements[1])
boundsElements[1] = testElements[1];
if (testElements[2] < boundsElements[2])
boundsElements[2] = testElements[2];
if (testElements[3] > boundsElements[3])
boundsElements[3] = testElements[3];
}
}
else
{
/*It doesn't have a bounds*/
if (firstTime)
{
/*Try to use my bounds*/
if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
&& DIMS(myBounds)[0] == 4)
{
Array2CArray(boundsElements, myBounds);
}
else
{
doubleNoBounds = true;
}
}
}
firstTime = false;
}
}
button = GetVar(object, DENSERBUTTON);
if (button)
{
test = BoundsInvalid(button, changeCount);
if (test)
{
/*Hey, the scroll bar needs redrawing*/
if (IsRealArray(test))
{
/*It has a bounds*/
if (firstTime)
{
Array2CArray(boundsElements, test);
}
else
{
Array2CArray(testElements, test);
if (testElements[0] < boundsElements[0])
boundsElements[0] = testElements[0];
if (testElements[1] > boundsElements[1])
boundsElements[1] = testElements[1];
if (testElements[2] < boundsElements[2])
boundsElements[2] = testElements[2];
if (testElements[3] > boundsElements[3])
boundsElements[3] = testElements[3];
}
}
else
{
/*It doesn't have a bounds*/
if (firstTime)
{
/*Try to use my bounds*/
if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
&& DIMS(myBounds)[0] == 4)
{
Array2CArray(boundsElements, myBounds);
}
else
{
doubleNoBounds = true;
}
}
}
firstTime = false;
}
}
button = GetVar(object, SPARSERBUTTON);
if (button)
{
test = BoundsInvalid(button, changeCount);
if (test)
{
/*Hey, the scroll bar needs redrawing*/
if (IsRealArray(test))
{
/*It has a bounds*/
if (firstTime)
{
Array2CArray(boundsElements, test);
}
else
{
Array2CArray(testElements, test);
if (testElements[0] < boundsElements[0])
boundsElements[0] = testElements[0];
if (testElements[1] > boundsElements[1])
boundsElements[1] = testElements[1];
if (testElements[2] < boundsElements[2])
boundsElements[2] = testElements[2];
if (testElements[3] > boundsElements[3])
boundsElements[3] = testElements[3];
}
}
else
{
/*It doesn't have a bounds*/
if (firstTime)
{
/*Try to use my bounds*/
if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
&& DIMS(myBounds)[0] == 4)
{
Array2CArray(boundsElements, myBounds);
}
else
{
doubleNoBounds = true;
}
}
}
firstTime = false;
}
}
MakeVar(object, REPOBJ);
repObj = GetVar(object, REPOBJ);
if (repObj)
{
MakeVar(repObj, TRACKS);
tracks = GetVar(repObj, TRACKS);
if (tracks)
{
/*Draw the contents of the tracks*/
int downOffset, y, height, lowestTrack, shownHeight;
long k;
ObjPtr var, *elements;
if (scrollBar)
{
downOffset = (long) GetReal(GetValue(scrollBar));
}
else
{
downOffset = 0;
}
elements = ELEMENTS(tracks);
/*Search for a place to begin*/
y = -downOffset;
for (k = 0; k < DIMS(tracks)[0]; ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var)
{
height = GetInt(var);
if ((y - height) < 0) break;
y -= height;
}
}
if (k < DIMS(tracks)[0])
{
/*There's something to check*/
FuncTyp method;
lowestTrack = k;
shownHeight = myBoundsElements[3] - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP -
(myBoundsElements[2] + TC_GAP + BARWIDTH) - 2;
for (k = lowestTrack; (k < DIMS(tracks)[0]) && (y > -shownHeight); ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var)
{
height = GetInt(var);
if (BoundsInvalid(elements[k], changeCount))
{
real tl, tr, tb, tt;
tl = myBoundsElements[0] + 1;
tr = myBoundsElements[1] - 1;
tb = myBoundsElements[3] - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y - height,
tt = myBoundsElements[3] - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1 + y;
if (firstTime)
{
boundsElements[0] = tl;
boundsElements[1] = tr;
boundsElements[2] = tb;
boundsElements[3] = tt;
firstTime = false;
}
else
{
if (tl < boundsElements[0])
boundsElements[0] = tl;
if (tr > boundsElements[1])
boundsElements[1] = tr;
if (tb < boundsElements[2])
boundsElements[2] = tb;
if (tt > boundsElements[3])
boundsElements[3] = tt;
}
}
y -= height;
}
}
}
}
}
/*Now return the bounds*/
if (firstTime != true)
{
if (doubleNoBounds)
{
return ObjTrue;
}
else
{
ObjPtr retVal;
retVal = NewRealArray(1, 4L);
CArray2Array(retVal, boundsElements);
return retVal;
}
}
return NULLOBJ;
}
#ifdef PROTO
static void UpdateTrackReadouts(ObjPtr control)
#else
static void UpdateTrackReadouts(control)
ObjPtr control;
#endif
/*Updates the readouts in a track control*/
{
ObjPtr readout1, readout2, clock, format, var;
char timeStr[256];
char frameStr[256];
FuncTyp method;
real frameWidth, time;
readout1 = GetObjectVar("UpdateTrackReadouts", control, READOUT);
if (!readout1)
{
return;
}
readout2 = GetVar(control, READOUT2);
var = GetVar(control, VALUE);
if (var)
{
time = GetReal(var);
MakeVar(control, TIMEFORMAT);
format = GetVar(control, TIMEFORMAT);
if (format)
{
PrintTime(timeStr, time, GetInt(format));
}
else
{
sprintf(timeStr, "%g", time);
}
MakeVar(control, FRAMERATE);
var = GetVar(control, FRAMERATE);
if (var)
{
frameWidth = 1.0 / GetReal(var);
sprintf(frameStr, "%g", floor(time / frameWidth + 0.5));
}
else
{
strcpy(frameStr, "");
}
}
else
{
strcpy(timeStr, "");
strcpy(frameStr, "");
}
InhibitLogging(true);
if (readout1)
{
method = GetMethod(readout1, CHANGEDVALUE);
SetMethod(readout1, CHANGEDVALUE, (FuncTyp) 0);
SetTextBox(readout1, timeStr);
SetMethod(readout1, CHANGEDVALUE, method);
}
if (readout2)
{
method = GetMethod(readout2, CHANGEDVALUE);
SetMethod(readout2, CHANGEDVALUE, (FuncTyp) 0);
SetTextBox(readout2, frameStr);
SetMethod(readout2, CHANGEDVALUE, method);
}
InhibitLogging(false);
}
static ObjPtr KeyDownTrackControl(object, key, flags)
ObjPtr object;
int key;
long flags;
/*Does a keydown in a track control*/
{
ObjPtr readout;
if (key == 0)
{
/*Do nothing with timeout*/
return ObjTrue;
}
if (AmICurrent(object) &&
(key == FK_LEFT_ARROW || key == FK_RIGHT_ARROW ||
key == FK_UP_ARROW || key == FK_DOWN_ARROW))
{
/*It's a keypress here*/
ObjPtr var;
real value, frameWidth;
MakeVar(object, FRAMERATE);
var = GetVar(object, FRAMERATE);
if (!var)
{
return ObjTrue;
}
frameWidth = 1.0 / GetReal(var);
var = GetRealVar("KeyDownTrackControl", object, VALUE);
if (!var)
{
return ObjTrue;
}
value = GetReal(var);
#ifdef INTERACTIVE
DrawInteractive(false);
#endif
switch (key)
{
case FK_LEFT_ARROW:
SetValue(object, NewReal((floor(value / frameWidth) - 1.0) * frameWidth));
break;
case FK_RIGHT_ARROW:
SetValue(object, NewReal((floor(value / frameWidth) + 1.0) * frameWidth));
break;
}
AutoScroll(object);
}
readout = GetVar(object, READOUT);
if (readout && AmICurrent(readout))
{
return KeyDownObject(readout, key, flags);
}
readout = GetVar(object, READOUT2);
if (readout && AmICurrent(readout))
{
return KeyDownObject(readout, key, flags);
}
return ObjFalse;
}
static ObjPtr PressTrackControl(object, x, y, flags)
ObjPtr object;
int x, y;
long flags;
/*Does a press in a track control beginning at x and y. Returns
true iff the press really was in the control.*/
{
#ifdef INTERACTIVE
int left, right, bottom, top;
ObjPtr scrollbar, textBox, button;
int leftWidth;
ObjPtr var;
Get2DIntBounds(object, &left, &right, &bottom, &top);
/*Kludge to make it not flash*/
SetVar(object, OPAQUE, ObjTrue);
/*See if it's a press in a scrollbar*/
scrollbar = GetVar(object, HSCROLL);
if (scrollbar)
{
if (IsTrue(PressObject(scrollbar, x, y, flags)))
{
return ObjTrue;
}
}
scrollbar = GetVar(object, VSCROLL);
if (scrollbar)
{
if (IsTrue(PressObject(scrollbar, x, y, flags)))
{
return ObjTrue;
}
}
/*Now the readouts*/
textBox = GetVar(object, READOUT);
if (textBox)
{
if (IsTrue(PressObject(textBox, x, y, flags)))
{
return ObjTrue;
}
}
textBox = GetVar(object, READOUT2);
if (textBox)
{
if (IsTrue(PressObject(textBox, x, y, flags)))
{
return ObjTrue;
}
}
/*Now the buttons*/
button = GetVar(object, DENSERBUTTON);
if (button)
{
if (IsTrue(PressObject(button, x, y, flags)))
{
return ObjTrue;
}
}
/*Now the buttons*/
button = GetVar(object, SPARSERBUTTON);
if (button)
{
if (IsTrue(PressObject(button, x, y, flags)))
{
return ObjTrue;
}
}
var = GetIntVar("DrawTrackControl", object, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
if (x >= left && x <= right && y >= bottom && y <= top)
{
/*Hey! It really was a click in the track control*/
ObjPtr tracks;
ObjPtr vScroll;
long downOffset;
ObjPtr repObj;
if (TOOL(flags) == T_ROTATE)
{
flags |= F_EXTEND;
}
if (x >= left + leftWidth + TC_GAP && x <= left + leftWidth + TC_GAP + BARWIDTH &&
y >= bottom && y <= bottom + BARWIDTH)
{
/*It's a press in the shape adjust control*/
int newX, newY;
int baseX;
int newLeftWidth, oldLeftWidth;
Bool insideP;
SetVar(object, OPAQUE, ObjFalse);
baseX = x;
OverDraw(true);
oldLeftWidth = leftWidth;
insideP = true;
EraseAll();
#ifdef SCROLLINMIDDLE
FrameUIRect(left, left + leftWidth, bottom + TC_GAP + BARWIDTH,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIRED);
#else
FrameUIRect(left + BARWIDTH + TC_GAP, left + BARWIDTH + TC_GAP + leftWidth, bottom + TC_GAP + BARWIDTH,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIRED);
#endif
FrameUIRect(left + leftWidth + 2 * TC_GAP + BARWIDTH,
right,
bottom + TC_GAP + BARWIDTH,
top, UIRED);
while (Mouse(&newX, &newY))
{
if (newX != x || newY != y)
{
x = newX;
y = newY;
/*Mouse has moved. First see about a transition*/
if (insideP)
{
if (newX < left || newX > right ||
newY < bottom || newY > top)
{
/*Transition to outside*/
insideP = false;
EraseAll();
leftWidth = oldLeftWidth;
#ifdef SCROLLINMIDDLE
FrameUIRect(left, left + leftWidth, bottom + TC_GAP + BARWIDTH,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIRED);
#else
FrameUIRect(left + BARWIDTH + TC_GAP, left + BARWIDTH + TC_GAP + leftWidth, bottom + TC_GAP + BARWIDTH,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIRED);
#endif
FrameUIRect(left + leftWidth + 2 * TC_GAP + BARWIDTH,
right,
bottom + TC_GAP + BARWIDTH,
top, UIRED);
continue;
}
}
else
{
if (newX < left || newX > right ||
newY < bottom || newY > top)
{
/*Still outside*/
continue;
}
else
{
insideP = true;
}
}
/*Make a new left width*/
newLeftWidth = oldLeftWidth + newX - baseX;
if (newLeftWidth < MINNAMESPACE) newLeftWidth = MINNAMESPACE;
if (newLeftWidth > right - left - MINNOTNAMESPACE) newLeftWidth = right - left - MINNOTNAMESPACE;
if (newLeftWidth != leftWidth)
{
leftWidth = newLeftWidth;
EraseAll();
#ifdef SCROLLINMIDDLE
FrameUIRect(left, left + leftWidth, bottom + TC_GAP + BARWIDTH,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIRED);
#else
FrameUIRect(left + BARWIDTH + TC_GAP, left + BARWIDTH + TC_GAP + leftWidth, bottom + TC_GAP + BARWIDTH,
top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP, UIRED);
#endif
FrameUIRect(left + leftWidth + 2 * TC_GAP + BARWIDTH,
right,
bottom + TC_GAP + BARWIDTH,
top, UIRED);
}
}
}
EraseAll();
OverDraw(false);
if (leftWidth != oldLeftWidth)
{
/*Have to set it*/
int l, r, b, t;
SetVar(object, LEFTSIDEWIDTH, NewInt(leftWidth));
var = GetVar(object, READOUT);
if (var)
{
Get2DIntBounds(var, &l, &r, &b, &t);
r += leftWidth - oldLeftWidth;
Set2DIntBounds(var, l, r, b, t);
}
var = GetVar(object, READOUT2);
if (var)
{
Get2DIntBounds(var, &l, &r, &b, &t);
r += leftWidth - oldLeftWidth;
Set2DIntBounds(var, l, r, b, t);
}
/*Adjust the buttons*/
var = GetVar(object, SPARSERBUTTON);
if (var)
{
Get2DIntBounds(var, &l, &r, &b, &t);
r += leftWidth - oldLeftWidth;
l += leftWidth - oldLeftWidth;
Set2DIntBounds(var, l, r, b, t);
}
var = GetVar(object, DENSERBUTTON);
if (var)
{
Get2DIntBounds(var, &l, &r, &b, &t);
r += leftWidth - oldLeftWidth;
l += leftWidth - oldLeftWidth;
Set2DIntBounds(var, l, r, b, t);
}
#ifdef SCROLLINMIDDLE
var = GetVar(object, VSCROLL);
if (var)
{
Get2DIntBounds(var, &l, &r, &b, &t);
l += leftWidth - oldLeftWidth;
r += leftWidth - oldLeftWidth;
Set2DIntBounds(var, l, r, b, t);
}
#endif
var = GetVar(object, HSCROLL);
if (var)
{
Get2DIntBounds(var, &l, &r, &b, &t);
l += leftWidth - oldLeftWidth;
Set2DIntBounds(var, l, r, b, t);
}
ImInvalid(object);
RecalcScroll(object);
}
}
MakeMeCurrent(object);
vScroll = GetVar(object, VSCROLL);
if (vScroll)
{
downOffset = (long) GetReal(GetValue(vScroll));
}
else
{
downOffset = 0;
}
MakeVar(object, REPOBJ);
repObj = GetVar(object, REPOBJ);
if (!repObj) return ObjTrue;
MakeVar(repObj, TRACKS);
tracks = GetVar(repObj, TRACKS);
if (tracks)
{
#ifdef SCROLLINMIDDLE
if (x >= left + 1 && x <= left + leftWidth - 1 &&
y >= bottom + TC_GAP + BARWIDTH + 1 &&
y <= top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1)
#else
if (x >= left + BARWIDTH + TC_GAP + 1 &&
x <= left + BARWIDTH + TC_GAP + leftWidth - 1 &&
y >= bottom + TC_GAP + BARWIDTH + 1 &&
y <= top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 1)
#endif
{
/*It's a press in the names*/
int ty, height, k;
ObjPtr *elements;
elements = ELEMENTS(tracks);
/*Search for a place to begin*/
ty = -downOffset;
y -= top - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP - 2;
for (k = 0; k < DIMS(tracks)[0]; ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var)
{
height = GetInt(var);
if ((ty - height) < y &&
(ty >= y)) break;
ty -= height;
}
}
if (k < DIMS(tracks)[0])
{
/*Found a click*/
FuncTyp method;
method = GetMethod(elements[k], PRESSNAME);
if (method)
{
#ifdef SCROLLINMIDDLE
(*method)(elements[k], x - 1, y - ty, flags);
#else
(*method)(elements[k], x - 1 - BARWIDTH - TC_GAP, y - ty, flags);
#endif
}
}
else
{
if (!(flags & F_EXTEND))
{
DeselectAll();
}
}
}
}
if (TOOL(flags) == T_HELP)
{
ContextHelp(object);
return ObjTrue;
}
if(GetVar(object, VALUE) &&
x >= left + leftWidth + 2 * TC_GAP + BARWIDTH &&
x <= right &&
y >= top - TC_TIMEHEIGHT - TC_CURHEIGHT &&
y <= top - TC_TIMEHEIGHT)
{
/*It's a click in the current time slider*/
ObjPtr var;
real curTime, oldTime, lastTime;
real loValue, hiValue;
int timePixel;
int xOffset;
Bool inp; /*True iff in*/
int newX, newY; /*New x and y*/
real frameWidth; /*Frame width*/
int leftSide, rightSide; /*Sides for scroll*/
SaveForUndo(object);
MakeVar(object, FRAMERATE);
var = GetRealVar("PressTrackControl", object, FRAMERATE);
if (var)
{
frameWidth = 1.0 / GetReal(var);
}
else
{
frameWidth = 30.0;
}
var = GetVar(object, VALUE);
if (var)
{
curTime = GetReal(var);
}
else
{
curTime = 0.0;
}
var = GetVar(object, LOVALUE);
if (var)
{
loValue = GetReal(var);
}
else
{
loValue = 0.0;
}
var = GetVar(object, HIVALUE);
if (var)
{
hiValue = GetReal(var);
}
else
{
hiValue = 60.0;
}
timePixel = TimeToPixel(object, curTime);
oldTime = curTime;
lastTime = curTime;
if (x >= timePixel - TCCURWIDTH / 2 && x <= timePixel + TCCURWIDTH / 2)
{
/*It's a click on the thumb. Set offset*/
xOffset = timePixel - x;
}
else
{
/*No offset*/
xOffset = 0;
}
/*Start off inside*/
inp = true;
SetVar(object, HIGHLIGHTED, ObjTrue);
DrawMe(object);
/*Get bounds for scrolling*/
leftSide = left + leftWidth + 2 * TC_GAP + BARWIDTH + 1 + TCSCROLLBORDER;
rightSide = right - 1 - TCSCROLLBORDER;
if (x < leftSide) leftSide = x;
if (x > rightSide) rightSide = x;
var = NewRealArray(1, 2L);
((real *) ELEMENTS(var))[0] = leftSide;
((real *) ELEMENTS(var))[1] = rightSide;
SetVar(object, SCROLLBOUNDS, var);
/*Make current x and y bogus*/
x = -12345; y = -12345;
while (Mouse(&newX, &newY))
{
if (newX != x)
{
x = newX;
y = newY;
/*Check to see if it's outside*/
if (y < top - TC_TIMEHEIGHT - TC_CURHEIGHT - SLOP ||
y > top - TC_TIMEHEIGHT + SLOP)
{
/*Yes, it's outside*/
if (inp)
{
/*Transition from in to out*/
lastTime = oldTime;
SetVar(object, VALUE, NewReal(oldTime));
UpdateTrackReadouts(object);
SetVar(object, HIGHLIGHTED, ObjFalse);
inp = false;
if (AutoScroll(object))
{
x = -12345;
}
DrawMe(object);
}
}
else
{
/*No, it's inside*/
if (!inp)
{
/*Transition from out to in*/
inp = true;
SetVar(object, HIGHLIGHTED, ObjTrue);
}
curTime = PixelToTime(object, x + xOffset);
if (curTime < loValue - frameWidth * 0.5)
{
curTime = loValue;
}
if (curTime > hiValue - frameWidth * 0.5)
{
curTime = hiValue - frameWidth;
}
curTime = floor(curTime / frameWidth + 0.5) * frameWidth;
if (curTime != lastTime)
{
SetVar(object, VALUE, NewReal(curTime));
UpdateTrackReadouts(object);
if (AutoScroll(object))
{
x = -12345;
}
DrawMe(object);
lastTime = curTime;
}
}
}
}
SetVar(object, SCROLLBOUNDS, NULLOBJ);
if (inp)
{
SetVar(object, HIGHLIGHTED, ObjFalse);
if (logging)
{
LogControl(object);
}
ChangedValue(object);
}
ImInvalid(object);
}
#endif
return ObjTrue;
}
else
{
return ObjFalse;
}
}
static ObjPtr RecalcTrackControlScroll(control)
ObjPtr control;
/*Recalculates the scroll of the track control*/
{
ObjPtr repObj, tracks, scrollBar, var;
long totalHeight, shownHeight, k;
ObjPtr *elements;
int l, r, b, t;
real sliderDown;
real loValue, hiValue;
real portionShown;
int pixWidth;
int leftWidth;
Get2DIntBounds(control, &l, &r, &b, &t);
repObj = GetObjectVar("RecalcTrackControlScroll", control, REPOBJ);
if (!repObj) return ObjFalse;
var = GetIntVar("RecalcTrackControlScroll", control, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
/*Do vertical scroll*/
/*Calculate the total height*/
totalHeight = 0;
tracks = GetVar(repObj, TRACKS);
if (tracks)
{
elements = ELEMENTS(tracks);
for (k = 0; k < DIMS(tracks)[0]; ++k)
{
MakeVar(elements[k], TRACKHEIGHT);
var = GetVar(elements[k], TRACKHEIGHT);
if (var && IsInt(var))
{
totalHeight += GetInt(var);
}
}
}
/*Slop at the bottom*/
totalHeight += TC_CELLHEIGHT;
/*Calculate the numbers for the vertical scroll bar*/
shownHeight = t - TC_CURHEIGHT - TC_TIMEHEIGHT - TC_GAP -
(b + TC_GAP + BARWIDTH) - 2;
sliderDown = shownHeight - totalHeight;
if (sliderDown > 0.0) sliderDown = 0.0;
portionShown = (real) shownHeight;
/*Set the v scroll*/
scrollBar = GetVar(control, VSCROLL);
if (scrollBar)
{
SetSliderRange(scrollBar, 0.0, (real) sliderDown, TC_CELLHEIGHT);
SetPortionShown(scrollBar, portionShown);
}
/*Do horizontal scroll*/
var = GetRealVar("RecalcTrackControlScroll", control, LOVALUE);
if (var)
{
loValue = GetReal(var);
}
else
{
loValue = 0.0;
}
var = GetRealVar("RecalcTrackControlScroll", control, HIVALUE);
if (var)
{
hiValue = GetReal(var);
}
else
{
hiValue = 60.0;
}
pixWidth = (r - 1) - (l + leftWidth + 2 * TC_GAP + BARWIDTH + 1);
var = GetRealVar("RecalcTrackControlScroll", control, TIMEPERPIXEL);
if (var)
{
portionShown = GetReal(var) * pixWidth;
}
else
{
portionShown = hiValue - loValue;
}
scrollBar = GetVar(control, HSCROLL);
if (scrollBar)
{
real min, max;
min = loValue + portionShown * (0.5 - TC_MARGIN);
max = hiValue - portionShown * (0.5 - TC_MARGIN);
if (min > max)
{
min = (min + max) * 0.5;
max = min;
}
SetSliderRange(scrollBar, min, max, portionShown / 10.0);
SetPortionShown(scrollBar, portionShown);
}
return ObjTrue;
}
static ObjPtr AutoScrollTrackControl(control)
ObjPtr control;
/*Auto scrolls a time control*/
{
ObjPtr var;
int leftWidth;
int leftSide, rightSide;
var = GetIntVar("PixelToTime", control, LEFTSIDEWIDTH);
if (var)
{
leftWidth = GetInt(var);
}
else
{
leftWidth = 100;
}
var = GetVar(control, VALUE);
if (var)
{
int left, right, bottom, top, timePix;
ObjPtr slider;
real value, testVal, midVal, lo, hi;
value = GetReal(var);
Get2DIntBounds(control, &left, &right, &bottom, &top);
slider = GetObjectVar("AutoScrollTimeControl", control, HSCROLL);
if (!slider)
{
return ObjFalse;
}
GetSliderRange(slider, &lo, &hi);
var = GetVar(control, SCROLLBOUNDS);
if (var)
{
leftSide = ((real *) ELEMENTS(var))[0];
rightSide = ((real *) ELEMENTS(var))[1];
}
else
{
leftSide = left + leftWidth + 2 * TC_GAP + BARWIDTH + 1 + TCSCROLLBORDER;
rightSide = right - 1 - TCSCROLLBORDER;
}
testVal = PixelToTime(control, leftSide);
if (value < testVal)
{
/*It's off to the left*/
SetSliderValue(slider, GetSliderValue(slider) + value - testVal);
return ObjTrue;
}
testVal = PixelToTime(control, rightSide);
if (value > testVal)
{
/*It's off to the right*/
SetSliderValue(slider, GetSliderValue(slider) + value - testVal);
return ObjTrue;
}
return ObjFalse;
}
else
{
return ObjFalse;
}
}
static ObjPtr MakeTrackControlAppearance(control)
ObjPtr control;
/*Makes the appearance of a track control*/
{
RecalcScroll(control);
SetVar(control, APPEARANCE, ObjTrue);
return ObjTrue;
}
void InitTrackControls()
/*Initializes the track controls*/
{
pictureButtonClass = NewObject(buttonClass, 0L);
AddToReferenceList(pictureButtonClass);
SetMethod(pictureButtonClass, DRAW, DrawPictureButton);
densityButtonClass = NewObject(pictureButtonClass, 0L);
AddToReferenceList(densityButtonClass);
SetMethod(densityButtonClass, DRAWCONTENTS, DrawDensityButtonContents);
trackControlClass = NewObject(controlClass, 0L);
AddToReferenceList(trackControlClass);
SetVar(trackControlClass, LEFTSIDEWIDTH, NewInt(110));
SetMethod(trackControlClass, DRAW, DrawTrackControl);
SetMethod(trackControlClass, PRESS, PressTrackControl);
SetMethod(trackControlClass, BOUNDSINVALID, TrackControlBoundsInvalid);
SetMethod(trackControlClass, RESHAPE, ReshapeTrackControl);
DeclareDependency(trackControlClass, APPEARANCE, HIGHLIGHTED);
DeclareIndirectDependency(trackControlClass, APPEARANCE, REPOBJ, TRACKS);
SetMethod(trackControlClass, APPEARANCE, MakeTrackControlAppearance);
SetMethod(trackControlClass, RECALCSCROLL, RecalcTrackControlScroll);
SetMethod(trackControlClass, AUTOSCROLL, AutoScrollTrackControl);
SetMethod(trackControlClass, KEYDOWN, KeyDownTrackControl);
SetVar(trackControlClass, OPAQUE, ObjTrue);
AddSnapVar(trackControlClass, TIMEPERPIXEL);
}
void KillTrackControls()
/*Kills the track controls*/
{
RemoveFromReferenceList(trackControlClass);
RemoveFromReferenceList(densityButtonClass);
RemoveFromReferenceList(pictureButtonClass);
}